package inutan.login.service;

import inutan.common.entity.GatewayServerInfo;
import inutan.common.generator.UserTokenCreator;
import inutan.common.message.ActionErrorEnum;
import inutan.login.entity.UserInfo;
import org.apache.logging.log4j.LogManager;
import org.ricks.common.json.JSONObject;
import org.ricks.common.utils.StringUtils;
import org.ricks.common.utils.TimeUtils;
import org.ricks.ioc.anno.Bean;
import org.ricks.orm.OrmContext;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

@Bean
public class LoginService {

    org.apache.logging.log4j.Logger logger = LogManager.getLogger(LoginService.class);

    /**
     * 其它环境 玩家与游戏节点有没有绑定
     * 如果已绑定 分配绑定的游戏节点
     * 如果未绑定 默认0由网关动态分配 或则 登录服直接分配好。登录服已经知道存活的业务节点
     * @param openId
     * @return
     */
    public JSONObject login(String openId) {
        var survivalGatewayList = OrmContext.me().loadAll(GatewayServerInfo.class)
                .stream()
                .filter(gateInfo -> gateInfo.getFlushTime() + 15_000 > TimeUtils.currentTimeMillis())
                .collect(Collectors.toList());

        //断言WEB GM配置了网关节点，存在可用网关节点
        ActionErrorEnum.gatewayAllowError.assertTrue(!survivalGatewayList.isEmpty());
        UserInfo userInfo = OrmContext.me().executeLoad(UserInfo.class,"select * from login_user_info where username = ? ", openId);
        if(Objects.isNull(userInfo)) {
            userInfo = new UserInfo();
            userInfo.setUserToken(UserTokenCreator.generate());
            userInfo.setUsername(openId);
            userInfo.setPassword(openId);
            userInfo.setGatewayAddress("127.0.0.1:52052");
            userInfo.setLoginTime(TimeUtils.currentTimeMillis());
            OrmContext.me().insert(userInfo);
            return loginReturn(userInfo);
        }

        userInfo.setUserToken(UserTokenCreator.generate());
        userInfo.setLoginTime(TimeUtils.currentTimeMillis());
        OrmContext.me().update(userInfo);
        if(StringUtils.isBlank( userInfo.getGatewayAddress()) || !checkGatewaySurvival(survivalGatewayList, userInfo.getGatewayAddress())) {
            //说明玩家未绑定网关节点 或者 绑定的网关节点已经处于死亡状态。重新分配网关节点
            /**
             *         //gatewayId 排序
             *         gatewayServerInfoList.sort((a,b) -> a.getGatewayId() - b.getGatewayId());
             *
             *         int allowIndex = Math.abs(openId.hashCode() % gatewayServerInfoList.size());
             *         GatewayServerInfo gatewayServerInfo = gatewayServerInfoList.get(allowIndex);
             *         1.简单取余分配
             *         2.hash一致性均衡分配
             *         3.gateway kcp连接，最少分配
             *
             */
            userInfo.setGatewayAddress("127.0.0.1:52052");
        }

        return loginReturn(userInfo);
    }

    public JSONObject loginReturn(UserInfo userInfo) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("userToken", userInfo.getUserToken());
        jsonObject.put("gatewayInfo", userInfo.getGatewayAddress());
        jsonObject.put("loginTime", userInfo.getLoginTime());
        jsonObject.put("status", 0);
        return jsonObject;
    }


    /**
     *
     * @param survivalGatewayList 存活的网关节点
     * @param bindGatewayAddress 玩家绑定的网关远程地址
     * @return
     */
    private boolean checkGatewaySurvival(List<GatewayServerInfo> survivalGatewayList , String bindGatewayAddress) {
        return survivalGatewayList.stream().anyMatch(gatewayServerInfo -> gatewayServerInfo.getRemoteAddress().equals(bindGatewayAddress));
    }


    public String verifyUserToken(long userTokenId) {
        UserInfo userInfo = null;
//        Map map = MapUtils.newHashMap();
//        map.put("userTokenId", userTokenId);
//        UserVo userVo = userDao.load(map);
//        if (userVo != null) {
//            if (TimeUtils.getDeadLine(userVo.getLoginTime(), 5L, TimeUtils.MIN) > TimeUtils.currentTimeMillis()) {  //token 五分钟有效
//                return JSON.toJsonStr(new BrokerMessageVo(userVo.getUsername(), userTokenId, userVo.getId(), userVo.getPublisher(), userVo.getLoginTime()));
//            } else return JSON.toJsonStr(new BrokerMessageVo(ResponseStatus.userToken_error));
//        } else return JSON.toJsonStr(new BrokerMessageVo(ResponseStatus.userToken_error));
        return "";
    }

    public void changeBindBusiness(int businessId,long userId) {
//        String changeBindBusinessSql;
//        if(userId > 0) {
//            changeBindBusinessSql = "update user_vo set businessId = ? where id = ? ";
//            userDao.update(changeBindBusinessSql, businessId,userId);
//            return;
//        }
//        changeBindBusinessSql = "update user_vo set businessId = 0 where businessId = ? ";
//        userDao.update(changeBindBusinessSql, businessId);
    }


//    public void test() {
//        userDao.load(111L);
//    }
}
